<?php

namespace app\pay\controller;

use app\pay\service\Hqdeg;
use think\Db;
use app\pay\model\Plan;

//环球小额还款 0.75+1
class Payhqdeg extends Base
{
	protected $channel;
	protected $channel_name;
	protected $rate_rate = "0.0085";
	protected $rate_close_rate = "1";
	public function __construct()
	{
		parent::__construct();
		$this->channel = (new Hqdeg());
		$this->channel_name = "Payhqdeg";
	}

	/**
	 * 商户注册 信用卡
	 *
	 * @param string $pay_id 【[渠道id]】
	 * @param string $uid 【用户id】
	 * @param string $cid 【银行卡id】
	 *
	 * @return array
	 */
	public function register($pay_id = '', $uid = '', $cid = "")
	{
		if (empty($pay_id) || empty($uid)) {
			return ['error' => 1, 'msg' => '参数错误'];
		}
		$payment_public = $this->payment_public($pay_id, $uid, $cid, 'hqde', 1, 1);
		if ($payment_public['error'] != 0) {
			return $payment_public;
		}


		$payment_user = $payment_public['payment_user'];
		$user = $payment_public['user'];
		$card = $payment_public['card'];


		//接口1：商户接口报件
		$param = [
			"ordersn" => $payment_user["user_number"],//流水号
			"dsorderid" => $payment_user["user_number"],//商户订单号
			"bankcard" => $card["card_no"],//银行卡号
			"username" => $card['card_name'],//真实姓名
			"idcard" => $user['user_idcard'],//身份证号
			"mobile" => $card['card_phone'],//预留手机号
			"futureRateValue" => $this->rate_rate*100,//扣款费率如：0.5 表示0.5%
			"fixAmount" => $this->rate_close_rate*100,//还款手续费以分为单位，不能有小数点
		];
		//halt($param);
		$regRes = $this->channel->register($param);unset($param);
		//halt($regRes);
		if ($regRes["returncode"] == "0000" || $regRes["returncode"] == "0052") {
			$this->payment_register($payment_user, 1, $regRes["errtext"], $regRes['subMerchantNo']);
			return ['error' => 0, 'msg' => '入驻成功'];
		} else {
			return ['error' => 1, 'msg' => "商户注册失败：" . $regRes["errtext"]];
		}
	}

	/**
	 * 修改卡号和费率
	 * @Author tw
	 *
	 * @param string $pay_id [description]
	 * @param string $uid [description]
	 *
	 * @return [type]         [description]
	 */
	public function update_fee($pay_id = '', $uid = '')
	{

	}

	/**
	 * 子商户入网查询
	 * @Author tw
	 * @Date   2018-10-09
	 * @return [type]     [description]
	 */
	public function network_query()
	{
		return json(['error' => 0, 'msg' => '入驻成功']);
	}


	/**
	 * 绑定信用卡
	 *
	 * @param string $pay_id 【渠道id】
	 * @param string $uid 【用户id】
	 * @param string $cid 【信用卡id】
	 * @param string $type 【绑卡类型；1网页绑卡2api绑卡】
	 *
	 * @return array
	 */
	public function bind_card($pay_id = '', $uid = '', $cid = '', $type = '1')
	{
		if (empty($pay_id) || empty($uid) || empty($cid)) {
			return ['error' => 1, 'msg' => '参数错误'];
		}

		$payment_public = $this->payment_public($pay_id, $uid, $cid, "", 2, 1);
		if ($payment_public['error'] != 0) {
			return $payment_public;
		}

		$payment_user = $payment_public['payment_user'];
		$user = $payment_public['user'];
		$card = $payment_public['card'];

		$payment_card = Db::name('payment_card')->where('card_cid', $cid)->where('card_uid', $uid)->where('card_pay_id', $pay_id)->find();
		if (empty($payment_card)) {
			$payment_card['card_uid'] = $uid;
			$payment_card['card_pay_id'] = $pay_id;
			$payment_card['card_pay_uid'] = $payment_user['user_id'];
			$payment_card['card_cid'] = $cid;
			$payment_card['card_type'] = 1;
			$payment_card['card_no'] = $card['card_no'];
			$payment_card['card_state'] = 3;
			$payment_card['card_form_no'] = get_order_sn("B", $uid);
			$payment_card['card_time'] = time();
			$payment_card['card_id'] = Db::name('payment_card')->insertGetId($payment_card);
		} elseif ($payment_card['card_state'] == 1) {
			//return ['error'=>1,'msg'=>'卡已绑定'];
		} elseif ($payment_card['card_state'] == 3 && (time() - $payment_card['card_time']) < 10 * 60) {
			//return ['error'=>1,'msg'=>'验证已提交,等待审核，10分钟后重试'];
		}
		//halt($payment_public);
		//接口1：开始绑卡
		$param = [
			"ordersn" => $payment_card["card_form_no"],//流水号
			"dsorderid" => $payment_card["card_form_no"],//商户订单号
			"subMerchantNo" => $payment_user['user_merchant'],//子商户号
			"bankcard" => $card['card_no'],//银行卡
			"username" => $card['card_name'],//姓名
			"idcard" => $user['user_idcard'],//身份证
			"mobile" => $card['card_phone'],//手机号
			"cardType" => "02",
			"cvn2" => $card["card_cvn"],
			"expireDate" => $card["card_exp_date"],
			"returnUrl" => config("app_host") . "/pay/{$this->channel_name}/bind_card_return",//前台跳转地址
			"notifyUrl" => config("app_host") . "/pay/{$this->channel_name}/bind_card_notify"//异步通知地址
		];
		//halt($param);
		$res = $this->channel->bindCard($param);
		//dump($res);
		if ($res["returncode"] == '0055') {
			if (isset($res["bindId"]) && !empty($res["bindId"])) {
				$this->payment_bind_card($payment_card, 1, '大额绑卡', $res['bindId'], $res['dsorderid'], ["card_no" => $card["card_no"]]);
				return ['error' => 0, 'msg' => '绑卡成功，请继续操作！', 'returnUrl' => ""];
			}
		}
		if ($res["returncode"] == '0000') {
			if (isset($res["bindId"]) && !empty($res["bindId"])) {
				$this->payment_bind_card($payment_card, 1, '大额绑卡', $res['bindId'], $res['dsorderid']);
				return ['error' => 0, 'msg' => '绑卡成功，请继续操作！', 'returnUrl' => ""];
			} else {
				$this->payment_bind_card($payment_card, 3, '大额绑卡', "", $res['ordersn']);
				if (isset($res["bindUrl"]) && !empty($res["bindUrl"])) {
					return ['error' => 0, 'msg' => '绑卡待进一步验证，即将跳转验证页面', 'returnUrl' => $res['bindUrl']];
				}
				if (isset($res["joinType"]) && !empty($res["joinType"])) {
					//当returncode为0000时返回
					//HTML:返回HTML表单
					//URL:返回链接
				}
			}
		} else {
			$this->payment_bind_card($payment_card, 3, $res['errtext'], "", $res['ordersn']);
			return ['error' => 1, 'msg' => $res['errtext']];
		}
	}

	/**
	 * 绑卡回调
	 * @Author tw
	 * @Date   2018-10-09
	 * @return [type]     [description]
	 */
	public function bind_card_notify()
	{
		$post = input('post.');
		if (empty($post)) {
			return json(['error' => 1, 'msg' => '参数错误']);
		}
		//创建记录
		$this->notify_logs($post, 'hqdebindcard');

		$payment_card = Db::name('payment_card')->where('card_form_no', $post['dsorderid'])->find();
		if (empty($payment_card) || $payment_card['card_state'] != 3) {
			echo '请先提交绑卡信息';
			exit();
		} elseif ($post['status'] == '00') {    //绑卡成功
			$this->payment_bind_card($payment_card, 1, "绑卡成功", $post['bindId']);
		} else if ($post["status"] == "02") {
			//绑卡失败
			$this->payment_bind_card($payment_card, 2, "绑卡失败", "");
		}
		echo 'SUCCESS';
	}

	public function bind_card_return(){
		echo "<script>window.close();</script>";
	}

	public function unbind_card($pay_id, $uid, $cid)
	{
		return ['error' => 0, 'msg' => "暂未开发此功能"];
	}


	/**
	 * 代偿
	 * $type 用户判断是否是后台访问
	 *
	 * @param $mission
	 * @param $plan
	 *
	 * @return array
	 */
	public function pay($mission, $type = "api")
	{
		$uid = $mission["mission_uid"];
		$payment_public = [];
		$payment_card = [];
		$payment_user = [];
		$card = [];

		$res = $this->checkPay($mission, $type);

		if ($res["error"] != 0) {
			return json($res);
		} else {
			$card = $res["card"];
			$payment_card = $res["payment_card"];
			$payment_user = $res["payment_public"]['payment_user'];
		}
		$plan = Db::name('plan')
			->where(['plan_mid' => $mission['mission_id'], 'plan_state' => 0, 'plan_type' => $mission['mission_current_state']])
			->order("plan_pay_time ASC")
			->find();
		if (empty($plan)) {
			return ['error' => 2, 'msg' => '找不到执行计划'];
		}

		//file_put_contents("aaa.txt",var_export($plan,true)."\n\n",FILE_APPEND);
		//调用消费接口初始化一个数组
		$data = [];
		if (strtotime($plan["plan_pay_time"]) <= time() && $plan["plan_state"] == '0') {
		//if(1){
			//执行还款逻辑
			if ($plan["plan_type"] == "1") {
				//调用接口开始还款
				$data['ordersn'] = get_order_sn("", $uid); //流水号
				$data['dsorderid'] = $plan['plan_form_no'];//商户订单号
				$data['subMerchantNo'] = $payment_user['user_merchant'];//子商户账号
				$data['cardType'] = "02";//绑卡成功返回的bindId
				$data['bankcard'] = $card["card_no"];//银行卡号
				$data['amount'] = ($plan['plan_money']) * 100;//金额
				$data['userFee'] = $plan['plan_fee'] * 100;//手续费
				$data['bindId'] = $payment_card['card_pay_cid'];//绑卡成功返回的bindId
				$data['notifyUrl'] = config("app_host") . "/pay/{$this->channel_name}/pay_notify";//回调地址
				return $this->doPay($data, 'withDraw');
			}

			if ($plan["plan_type"] == '2') {
				//调用接口开始扣款
				$data['ordersn'] = get_order_sn("", $uid); //流水号
				$data['dsorderid'] = $plan['plan_form_no'];//商户订单号
				$data['subMerchantNo'] = $payment_user['user_merchant'];//子商户账号
				$data['bindId'] = $payment_card['card_pay_cid'];//绑卡成功返回的bindId
				$data['bankcard'] = $card["card_no"];//银行卡号
				$data['amount'] = (string)(($plan['plan_money'] + $plan['plan_fee'] + $plan["plan_fee2"]) * 100);//金额
				$data['userFee'] = (string)($plan['plan_fee'] * 100);//手续费
				$data['province'] = $this->getCityCodeByRegion($mission["mission_region_id"]);//消费城市
				$data['mcc'] = $plan["plan_mcc"];//行业xuan
				$data['notifyUrl'] = config("app_host") . "/pay/{$this->channel_name}/pay_notify";//回调地址
				//halt($data);
				return $this->doPay($data, 'pay');
			}
		} else {
			return ['error' => 1, 'msg' => '计划未到执行时间'];
		}
	}


	private function checkPay($mission, $type = "api")
	{
		$cid = $mission['mission_cid'];//信用卡id
		$pay_id = $mission['mission_pay_id'];//支付通道id
		$uid = $mission['mission_uid'];//用户id
		if (empty($pay_id) || empty($uid) || empty($cid)) {
			return ['error' => 1, 'msg' => '参数错误'];
		}
		$mission = Db::name('mission')->where('mission_id', $mission['mission_id'])->find();
		if ($mission["mission_type"] != '0' && $type == "api") {
			return ['error' => 1, 'msg' => '计划状态为：未启动，不能执行代付'];
		}
		if ($mission["mission_state"] != '1' && $type == "api") {
			return ['error' => 1, 'msg' => 'mission_state为：' . $mission["mission_type"]];
		}


		$payment_public = $this->payment_public($pay_id, $uid, $cid, "", 2);
		if ($payment_public['error'] != 0) {
			return $payment_public;
		}

		$card = Db::name('user_card')->where('card_uid', $uid)->where('card_id', $cid)->where('card_blocked', 0)->where('card_type', 1)->find();
		if (empty($card)) {
			return ['error' => 1, 'msg' => '支付卡不存在'];
		}

		$bank = Db::name('bank')->where('bank_pay_id', $pay_id)->where('bank_bid', $card['card_bank_id'])->find();
		if (empty($bank)) {
			return ['error' => 1, 'msg' => '不支持此银行'];
		}
		$payment_card = Db::name('payment_card')->where('card_cid', $cid)->where('card_uid', $uid)->where('card_pay_id', $pay_id)->find();
		if (empty($payment_card)) {
			return ['error' => 1, 'msg' => '通道没有绑卡'];
		}
		return [
			"error" => 0,
			"payment_public" => $payment_public,
			"card" => $card,
			"bank" => $bank,
			"payment_card" => $payment_card,
		];
	}


	//代偿逻辑执行
	private function doPay($data, $type)
	{
		if ($type == "pay") {//扣款
			$res = $this->channel->pay($data);
			$this->pay_logs(json_encode($data), json_encode($res), $this->channel_name, 'pay_kou');
		} else {
			$res = $this->channel->withDraw($data);
			$this->pay_logs(json_encode($data), json_encode($res), $this->channel_name, 'pay_huan');
		}
		dump($res);
		if (empty($res)) {
			return ['error' => 1, 'msg' => '通道未返回数据'];
		}
		//支付异常发起查询接口
		if ($res["returncode"] == "0002") {//0002支付异常不确定成功还是失败去查询
			controller("pay/task")->processed($res["dsorderid"]);
		}
		//暂时不走同步接口
		if (in_array($res["returncode"], ["0000", "0001", "0003"])) {//0000成功0001失败0003处理中
			return (new Plan)->payNotify($res, 1);//1是同步接口方法2异步接口方法
		}
		return ["error" => 2, "msg" => isset($res["errtext"]) ? $res["errtext"] : "未知错误"];
	}


	/**
	 * 扣款回调
	 * @return string|void
	 */
	public function pay_notify()
	{
		$post = input('post.');
		if (empty($post)) {
			$post = $_POST;
		}
		if (empty($post)) {
			$post = $_GET;
		}

		$this->notify_logs($post, $this->channel_name);
		if (empty($post) || !isset($post['status'])) {
			return json(['error' => 1, 'msg' => '参数错误']);
		}
		$notifyRes = (new Plan)->payNotify($post, 2);
		//回调成功以后再推送下一个队列
		if (in_array($post["status"], ["00"]) && $notifyRes["error"] == "0") {//00成功；01处理中
			//推送下一个plan
			controller("api/task")->index($notifyRes["mission_id"]);
			echo 'success';
			exit;
		}
		echo 'fail';
		exit;
	}


	/**
	 * 交易状态查询
	 * @Author tw
	 * @Date   2018-10-23
	 *
	 * @param  [type]     $plan [description]
	 *
	 * @return [type]           [description]
	 */
	public function query_order_status($plan, $is_push = true)
	{
		$pay_id = $plan['plan_pay_id'];//支付通道id
		$uid = $plan['plan_uid'];//用户id
		if (empty($pay_id) || empty($uid)) {
			return ['error' => 1, 'msg' => '参数错误'];
		}

		//公共参数
		$data['ordersn'] = get_order_sn("", $uid); //流水号
		$data['dsorderid'] = $plan['plan_form_no'];//商户订单号
		if ($plan['plan_type'] == 1) {
			$data['transtype'] = 136;//交易类型135交易(扣款)，136代付(还款)
		} elseif ($plan['plan_type'] == 2) {
			$data['transtype'] = 135;//交易类型135交易(扣款)，136代付(还款)
		}
		$res = $this->channel->queryOrder($data);
		if (empty($res)) {
			return ['error' => 1, 'msg' => '通道未返回数据'];
		}
		if ($is_push === true) {
			//$this->pay_logs(json_encode($data), json_encode($res), 'Payhqxe', 'query_order_status');
			if (in_array($res["status"], ["00"])) {
				$notifyRes = (new Plan)->payNotify($res, 2);
				if ($notifyRes["error"] == 0) {
					//推送下一个plan
					controller("api/task")->index($notifyRes["mission_id"]);
				}
			}
		} else {
			return ["error" => 0, "msg" => "查询结果：" . $res["message"]];
		}
	}


	public function autoHuan($order)
	{
		$uid = $order["uid"];
		$mchid = $order["user_merchant"];
		$bindid = $order["bindId"];//462
		$balance = $this->balance_query($uid, $mchid, $bindid);//halt($balance);
		if ($balance["error"] == '0' && $balance["amount"] > 2) {
			return $this->withDraw($order, $balance["amount"]);
		} else {
			return json($balance);
		}
	}

	public function withDraw($order, $money)
	{
		$uid = $order["uid"];
		$mchid = $order["user_merchant"];
		$bindid = $order["bindId"];//462
		$plan_form_no = $order["plan_form_no"];//462
		$card_no = Db::name("payment_card")->where("card_pay_id","=",$bindid)->value("card_no");
		$payData = [
			"ordersn" => get_order_sn("", $uid),//流水号
			"dsorderid" => $plan_form_no,//商户订单号
			"subMerchantNo" => $mchid,
			'cardType' => "02",//绑卡成功返回的bindId
			'bankcard' => $card_no,//银行卡号
			"bindId" => $bindid,
			"userFee" => 1 * 100,//交易手续费
			"amount" => ($money - 1) * 100,//金额
			"notifyUrl" => config("app_host") . '/pay/Huidiao/index'
		];
		$res = $this->channel->withDraw($payData);
		//dump($res);
		$data["status"] = $res["returncode"];
		$data["fail_money"] = $money;
		$data["fail_fee"] = 2;
		$data["fail_msg"] = $res["errtext"];
		if ($res["returncode"] == '0000') {
			$data["status"] = 1;
		} elseif ($res["status"] == '0001') {
			$data["status"] = 2;
			//$data["plan_form_no"] = get_order_sn("C", $uid);
		}
		//halt($data);
		Db::name("repayment_fail_log")->where(["plan_form_no" => $plan_form_no])->update($data);
		return json($res);
	}

	/**
	 * 查询子商户余额
	 * @Author tw
	 * @Date   2018-10-09
	 * @return [type]     [description]
	 */
	public function balance_query($uid = '', $subMerchantNo = "", $bindid = '')
	{
		$data = [
			"ordersn" => get_order_sn("", $uid),//流水号
			"dsorderid" => get_order_sn("Q", $uid),//商户订单号
			"subMerchantNo" => $subMerchantNo,
			"bindId" => $bindid,
		];
		$res = $this->channel->queryBalance($data);
		//halt($res);
		if ($res["returncode"] == "0000") {//$res["frozenamount"]当前冻结余额
			return ['error' => 0, 'msg' => '成功', 'amount' => $res["currAccountBalance"]];
		} else {
			return ['error' => 1, 'msg' => '获取余额失败', 'amount' => 0];
		}

	}


	public function pay_state_df($plan)
	{
		return $this->query_order_status($plan);
	}

	public function pay_state_kj($plan)
	{
		return $this->query_order_status($plan);
	}


	public function mcc($pay_id = '', $uid = '', $cid = '', $city_id = '0', $region = '')
	{
		return ['error' => 0, 'msg' => '成功', 'data' => [['mcc' => $region, 'name' => $region]]];

	}

	/**
	 * 查询市的行业信息 -传入示例山东省-济宁市
	 * @Author tw
	 *
	 * @param string $pay_id [description]
	 * @param string $uid [description]
	 * @param string $cid [description]
	 * @param string $province [description]
	 * @param string $city [description]
	 *
	 * @return [type]           [description]
	 */
	public function query_city_mcc($pay_id = '', $uid = '', $cid = '', $province = '', $city = '', $region = '')
	{
		return ['error' => 0, 'msg' => '成功', 'data' => [['mcc' => $region, 'name' => $region]]];

	}

	/**
	 * 获取所有城市
	 * @Author tw
	 *
	 * @param string $pay_id [description]
	 * @param string $uid [description]
	 * @param string $id [description]
	 *
	 * @return [type]         [description]
	 */
	public function city_all($pay_id = '', $uid = '', $id = '0')
	{
		$cacheName = $this->channel_name."city_all";
		if(cache("?{$cacheName}")){
			return ['error' => 0, 'msg' => '成功', 'data' => cache($cacheName)];
		}
		$province = Db::name('region')->where('region_type', 1)->select();
		foreach ($province as $k1 => $v1) {
			$city = Db::name('region')->where('region_type', 2)->where('region_pid', $v1['region_id'])->select();
			foreach ($city as $k2 => $v2) {
				$area = Db::name('region')->where('region_type', 3)->where('region_pid', $v2['region_id'])->select();
				foreach ($area as $k3 => $v3) {
					$children_area[$k3]['value'] = $v3['region_adcode'];
					$children_area[$k3]['text'] = $v3['region_name'];
				}
				$children_city[$k2]['value'] = $v2['region_adcode'];
				$children_city[$k2]['text'] = $v2['region_name'];
				$children_city[$k2]['children'] = $children_area;
			}
			$list[$k1]['value'] = $v1['region_adcode'];
			$list[$k1]['text'] = $v1['region_name'];
			$list[$k1]['children'] = $children_city;
			unset($children_city);
		}
		$list = array_values($list);//halt($list);
		cache($cacheName,$list,time()+8*3600);
		//$list = json_encode($list,JSON_UNESCAPED_UNICODE);
		return ['error' => 0, 'msg' => '成功', 'data' => $list];
	}

}